using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Data;
using Volo.Abp.Application.Dtos;
using Joy.Erp.BasicArchives.Permissions;
using Joy.Erp.BasicArchives.Core.Filters;

namespace Joy.Erp.BasicArchives.Procurements
{
    [Authorize]
    public class PurchaseRequisitionTypeAppService : BasicArchivesAppService, IPurchaseRequisitionTypeAppService
    {
        protected IPurchaseRequisitionTypeRepository PurchaseRequisitionTypeRepository => LazyServiceProvider.LazyGetRequiredService<IPurchaseRequisitionTypeRepository>();
        protected PurchaseRequisitionTypeManager PurchaseRequisitionTypeManager => LazyServiceProvider.LazyGetRequiredService<PurchaseRequisitionTypeManager>();

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Query)]
        public async Task<PurchaseRequisitionTypeDto> GetAsync(Guid id)
        {
            return ObjectMapper.Map<PurchaseRequisitionType, PurchaseRequisitionTypeDto>(
                await PurchaseRequisitionTypeRepository.GetAsync(id, true)
            );
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Query)]
        public async Task<PurchaseRequisitionTypeDto> FindAsync(string filter)
        {
            var entity = await PurchaseRequisitionTypeRepository.FindAsync(x => x.DisplayName == filter);
            return ObjectMapper.Map<PurchaseRequisitionType, PurchaseRequisitionTypeDto>(entity);
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Query)]
        public async Task<PurchaseRequisitionTypeDto> FindBySourceKeyAsync(string sourceKey, string sourceType)
        {
            var entity = await PurchaseRequisitionTypeRepository.FindAsync(x => x.SourceKey == sourceKey && x.SourceType == sourceType);
            return ObjectMapper.Map<PurchaseRequisitionType, PurchaseRequisitionTypeDto>(entity);
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Query)]
        public async Task<PagedResultDto<PurchaseRequisitionTypeDto>> GetListAsync(FilterRequestDto input)
        {
            var totalCount = await PurchaseRequisitionTypeRepository.GetCountAsync(input.Filter, true);
            var list = await PurchaseRequisitionTypeRepository.GetPagedListAsync(input.Filter, input.SkipCount, input.MaxResultCount, input.Sorting, true);

            return new PagedResultDto<PurchaseRequisitionTypeDto>(
                totalCount,
                ObjectMapper.Map<List<PurchaseRequisitionType>, List<PurchaseRequisitionTypeDto>>(list));
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Query)]
        public async Task<PagedResultDto<PurchaseRequisitionTypeDto>> QueryAsync(FilterGroupRequestDto input)
        {
            Expression<Func<PurchaseRequisitionType, bool>> expression = null;
            if (input != null && input.FilterGroup != null)
            {
                expression = FilterConverter.Convert<PurchaseRequisitionType>(input.FilterGroup);
            }

            var totalCount = await PurchaseRequisitionTypeRepository.GetCountAsync(expression, true);
            var list = await PurchaseRequisitionTypeRepository.GetPagedListAsync(expression, input.SkipCount, input.MaxResultCount, input.Sorting, true);

            return new PagedResultDto<PurchaseRequisitionTypeDto>(
                totalCount,
                ObjectMapper.Map<List<PurchaseRequisitionType>, List<PurchaseRequisitionTypeDto>>(list));
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Create)]
        public async Task<PurchaseRequisitionTypeDto> CreateAsync(PurchaseRequisitionTypeCreateDto input)
        {
            var entity = ObjectMapper.Map<PurchaseRequisitionTypeCreateDto, PurchaseRequisitionType>(input);

            await PurchaseRequisitionTypeManager.CreateAsync(entity, true);
            return await GetAsync(entity.Id);
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Update)]
        public async Task<PurchaseRequisitionTypeDto> UpdateAsync(Guid id, PurchaseRequisitionTypeUpdateDto input)
        {
            var entity = await PurchaseRequisitionTypeRepository.GetAsync(id);
            entity.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);

            ObjectMapper.Map(input, entity);

            await PurchaseRequisitionTypeManager.UpdateAsync(entity, true);
            return await GetAsync(entity.Id);
        }

        [Authorize(BasicArchivesPermissions.PurchaseRequisitionType.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            await PurchaseRequisitionTypeManager.DeleteAsync(id);
        }
    }
} 